/**
 * 
 */
package com.kcloud.zkem.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.kcloud.zkem.domain.LogData;

import java.util.*;

/**
 * @author guor
 *
 */
public class ZkemSDKUtils {
    public static int Machine_Number = 1;
	//zkemkeeper.ZKEM.1 为zkemkeeper.dll 注册成功后 在注册表可以查看：HKEY_CLASSES_ROOT最下面
    private static ActiveXComponent zkem = new ActiveXComponent("zkemkeeper.ZKEM.1");
    private boolean isconnect;
    /**
     * 连接考勤机
     *
     * @param address 考勤机地址
     * @param port    端口号，默认端口为 4370
     * @return true为成功，false为失败
     */
    public boolean connect(String address, int port) {
        isconnect = zkem.invoke("Connect_NET", address, port).getBoolean();
        return isconnect;
    }

    /**
     * 断开考勤机连接
     * @return true为成功，false为失败
     */
    public Variant disconnect() {
        Variant result = Dispatch.call(zkem,"Disconnect");
        return result;
    }
    /**
     * 读取考勤记录到pc缓存。配合getGeneralLogData使用
     *
     * @return true为成功，false为失败
     */
    public boolean readGeneralLogData() {
        boolean result = zkem.invoke("ReadGeneralLogData", Machine_Number).getBoolean();
        return result;
    }
    /**
     * 设置连接超时时间
     * @return true为成功，false为失败
     */
    public boolean disableDeviceWithTimeOut (){
    	boolean result =zkem.invoke("DisableDeviceWithTimeOut", Machine_Number, 60).getBoolean();
    	return result;
    }
    /**
     * 获取机器内数据存储状态
     * @param statusCode
     *  1 管理员数量
     *  2 注册用户数量
     *  3 机器内指纹模板数量
     *  4 密码数量
     *  5 操作记录数
     *  6 考勤记录数
     *  7 指纹模板容量
     *  8 用户容量
     *  9 考勤记录容量
     *  10 剩余指纹模板容量
     *  11 剩余用户数容量
     *  12 剩余考勤记录容量
     *  21 人脸总数
     *  22 人脸容量
     *  其他状况返回 0 
     * @return
     */
    public Integer getDeviceStatus (int statusCode){
    	 Variant status = new Variant(0, true);
    	 Variant vResult =Dispatch.call(zkem,"GetDeviceStatus",Machine_Number,statusCode,status);
         Integer result=0;
    	 if (vResult.getBoolean()) {
    		 result = status.getIntRef();
    	 }
    	 return result;
    }
    /**
     * 查詢所有/指定ID的打卡信息;
     * @param userNumber 员工编号，值为空时，为查询所有员工
     * @return
     */
    public List<LogData> getUserOneDayInfo(Object userNumber,String date){
        List<LogData> logDateList = new ArrayList<>();
        //连接考勤机；
        if(isconnect){
            List<Map<String, Object>> generalLogDataAll = this.getGeneralLogData(date);
            for (int i = 0; i < generalLogDataAll.size(); i++) {
//                System.out.println(generalLogDataAll.get(i).keySet().toString());
                String Year =String.valueOf(generalLogDataAll.get(i).get("Year"));
                String Hour = String.valueOf(generalLogDataAll.get(i).get("Hour"));
                String InOutMode = String.valueOf(generalLogDataAll.get(i).get("InOutMode"));
                String Time = String.valueOf(generalLogDataAll.get(i).get("Time"));
                String Second = String.valueOf(generalLogDataAll.get(i).get("Second"));
                String Minute = String.valueOf(generalLogDataAll.get(i).get("Minute"));
                String EnrollNumber = String.valueOf(generalLogDataAll.get(i).get("EnrollNumber"));
                String Day = String.valueOf(generalLogDataAll.get(i).get("Day"));
                String Month = String.valueOf(generalLogDataAll.get(i).get("Month"));
                String VerifyMode = String.valueOf(generalLogDataAll.get(i).get("VerifyMode"));
                LogData logData = new LogData();
                logData.setYear(Year);
                logData.setHour(Hour);
                logData.setInOutMode(InOutMode);
                logData.setTime(Time);
                logData.setSecond(Second);
                logData.setMinute(Minute);
                logData.setEnrollNumber(EnrollNumber);
                logData.setDay(Day);
                logData.setMonth(Month);
                logData.setVerifyMode(VerifyMode);

                if (EnrollNumber.equals(userNumber)&&userNumber!=null){
                    logDateList.add(logData);
                }else if (userNumber==null){
                    logDateList.add(logData);
                }
            }
            return logDateList;

        }
        return null;
    }
    /**
     * 
     * 获取缓存中的考勤数据。配合readGeneralLogData / readLastestLogData使用。
     * @param date 获取考勤的日期，如果为空为当前天 。日期格式为：yyyy-MM-dd
     * 
     * @return 返回的map中，包含以下键值：
     * "EnrollNumber"   人员编号
     * "Time"           考勤时间串，格式: yyyy-MM-dd HH:mm:ss
     * "VerifyMode"     验证方式  1：指纹 2：面部识别
     * "InOutMode"      考勤状态 0：上班 1：下班 2：外出 3：外出返回 4：加班签到 5：加班签退
     * "Year"          考勤时间：年
     * "Month"         考勤时间：月
     * "Day"           考勤时间：日
     * "Hour"            考勤时间：时
     * "Minute"        考勤时间：分
     * "Second"        考勤时间：秒
     * 
     */
    public List<Map<String, Object>> getGeneralLogData(String date) {
        Variant dwMachineNumber = new Variant(1, true);
        Variant dwEnrollNumber = new Variant("", true);
        Variant dwVerifyMode = new Variant(0, true);
        Variant dwInOutMode = new Variant(0, true);
        Variant dwYear = new Variant(0, true);
        Variant dwMonth = new Variant(0, true);
        Variant dwDay = new Variant(0, true);
        Variant dwHour = new Variant(0, true);
        Variant dwMinute = new Variant(0, true);
        Variant dwSecond = new Variant(0, true);
        Variant dwWorkCode = new Variant(0, true);
        List<Map<String, Object>> strList = new ArrayList<Map<String, Object>>();
        boolean newresult = false;
        do {
            Variant vResult = Dispatch.call(zkem, "SSR_GetGeneralLogData", dwMachineNumber, dwEnrollNumber, dwVerifyMode, dwInOutMode, dwYear, dwMonth, dwDay, dwHour, dwMinute, dwSecond, dwWorkCode);
            newresult = vResult.getBoolean();
            if (newresult) {
                String enrollNumber = dwEnrollNumber.getStringRef();

                //如果没有编号，则跳过。
                if (enrollNumber == null || enrollNumber.trim().length() == 0) {
                    continue;
                }
                //yyyy-MM-dd格式，对于M和d进行补位
                String month = dwMonth.getIntRef() + "";
                String day = dwDay.getIntRef() + "";
                if (dwMonth.getIntRef() < 10) {
                    month = "0" + dwMonth.getIntRef();
                }
                if (dwDay.getIntRef() < 10) {
                    day = "0" + dwDay.getIntRef();
                }
                String validDate = dwYear.getIntRef() + "-" + month + "-" + day;
                Date validDate_date = DateUtil.parse(validDate, "yyyy-MM-dd");
                if(ObjectUtil.isNull(date)){
                date = DateUtil.today();
                }
                long betweenDay = DateUtil.between(validDate_date, DateUtil.parse(date, "yyyy-MM-dd"), DateUnit.DAY);
//                System.out.println("时间差===validDate_date="+validDate_date+"===search_date===="+DateUtil.parse(date, "yyyy-MM-dd")+"=》"+betweenDay);
                if (betweenDay==0) {
                    Map<String, Object> m = new HashMap<String, Object>();
                    //Map<String, Object> user = getUserInfoByNumber(enrollNumber);
                    m.put("EnrollNumber", enrollNumber);
                    DateTime parse = DateUtil.parse(dwYear.getIntRef() + "-" + dwMonth.getIntRef() + "-" + dwDay.getIntRef() + " " + dwHour.getIntRef() + ":" + dwMinute.getIntRef() + ":" + dwSecond.getIntRef(),"yyyy-MM-dd HH:mm:ss");
                    m.put("Time",DateUtil.formatDateTime(parse) );
                    m.put("VerifyMode", dwVerifyMode.getIntRef());
                    m.put("InOutMode", dwInOutMode.getIntRef());
                    m.put("Year", dwYear.getIntRef());
                    m.put("Month", dwMonth.getIntRef());
                    m.put("Day", dwDay.getIntRef());
                    m.put("Hour", dwHour.getIntRef());
                    m.put("Minute", dwMinute.getIntRef());
                    m.put("Second", dwSecond.getIntRef());
                    strList.add(m);
                }
            }
        } while (newresult == true);
        return strList;
    }

}
